у тебя есть несколько проблем:
1)у тебя точка не удаляется и зависает в памяти что даёт утечки(лаги)
2)у тебя не устанавливается группа что даёт утечки(лаги) + нельзя отследить людей в ней
3)у тебя создаётся спецэффект, но не удаляется что даёт утечки(лаги)
Нужно создать переменную типа Отряд(то есть группа):
назвать её допустим GROUP
Нужно создать переменную типа Боевая единица:
назвать её допустим UNIT
нужно сделать так:
в триггере где событие ПРИМЕНЯЕТ СПОСОБНОСТЬ создать действие:
установить применяющий юнит = UNIT
установить FireStrike = случ точка в области Fire strike
установить группу GROUP = юниты в области 300 от Fire strike соответствующий юнит не равно UNIT
создать эффект
удалить эффект
call RemoveLocation(udg_FireStrike)
call DestroyGroup(udg_GROUP)
Bornikkeny, сделал специально чтобы доказать тебе что ты несёшь бред
даже 2 скрина приложил
думаю закинуть библиотеки сможешь сам (в папку *твой jngp*\AdicHelper\lib)
Хорошо группы реализуешь как альтернативу unit[array]. Я тоже самое получил. nvc123, и всё же твой хук не тот что мне нужен.
Я решил проблему, спасибо что дал идею обрабатывать движение внутри структуры, а не в стеке.
кот
library Hook initializer Init_Hook uses LibMath
globals
mhook ahook[100]
integer ihook = -1
endglobals
struct mhook
unit host = null
unit target = null
real face = 0
real speed = 0
real dis = 0
real dismax = 0
integer chaini = 0
unit chain[50]
real scale = 0
integer move = 1
integer i = 0
static method Create takes unit host, real tx, real ty, real scale returns mhook
local mhook h = mhook.create()
local integer i = GetPlayerId(GetOwningPlayer(host))
local real x = GetUnitX(host)
local real y = GetUnitY(host)
local real f = GetAngleXY(x,y,tx,ty)
set h.host = host
set h.face = f
set h.speed = 600
set h.dismax = 1400
set h.scale = scale
set h.chain[0] = CreateUnit(Player(i),'h007',GetPolarX(GetUnitX(host),f,h.scale/2),GetPolarY(GetUnitY(host),f,h.scale/2),f)
set h.i = i
call UnitAddAbility(h.chain[0],'Amrf')
call UnitAddAbility(h.chain[0],'Amrf')
call SetUnitFlyHeight(h.chain[0],50,0)
call SetUnitPathing(h.chain[0],false)
return h
endmethod
method Start takes nothing returns boolean
if ihook < 1000 then
set ihook = ihook + 1
set ahook[ihook] = this
return true
else
return false
endif
endmethod
method Destroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i > ihook
if ahook[i] == this then
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = ihook // выход из цикла
endif
set i = i + 1
endloop
set this.target = null
set this.host = null
call this.destroy()
endmethod
method Move takes nothing returns nothing
local integer i1 = 0
local integer l = 0
local real x
local real y
local real xh
local real yh
local real f
if move == 1
set dis = dis + speed*0.025
loop
exitwhen i1 > .chaini
set x = GetUnitX(.chain[i1])
set y = GetUnitY(.chain[i1])
if i1 > 0 then
set f = GetAngleXY(x,y,GetUnitX(.chain[i1-1]),GetUnitY(.chain[i1-1]))
call SetUnitX(.chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(.chain[i1],GetPolarY(y,f,.speed*0.025))
else
set f = face
call SetUnitX(chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(chain[i1],GetPolarY(y,f,.speed*0.025))
endif
call SetUnitFacing(chain[i1],f)
set i1 = i1 + 1
endloop
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set f = GetAngleXY(GetUnitX(.host),GetUnitY(.host),x,y)
set xh = GetPolarX(GetUnitX(.host),f,.scale/2)
set yh = GetPolarY(GetUnitY(.host),f,.scale/2)
//Create==================
if GetDisXY(xh,yh,x,y) >= .scale/2 then
set chaini = chaini + 1
set chain[chaini] = CreateUnit(Player(.i),'h007',xh,yh,f)
call UnitAddAbility(.chain[.chaini],'Amrf')
call UnitAddAbility(.chain[.chaini],'Amrf')
call SetUnitFlyHeight(.chain[.chaini],50,0)
endif
if dis > dismax then
set move = 0
endif
else
//REVERSE=============
set xh = GetUnitX(host)
set yh = GetUnitY(host)
set chain[chaini+1] = host
loop
exitwhen l > chaini
set x = GetUnitX(chain[l])
set y = GetUnitY(chain[l])
//if chain[chaini] == null then
// set f = GetAngleXY()
//endif
set f = GetAngleXY(x,y,GetUnitX(chain[l+1]),GetUnitY(chain[l+1]))
call SetUnitX(chain[l],GetPolarX(x,f,speed*0.025))
call SetUnitY(chain[l],GetPolarY(y,f,speed*0.025))
call SetUnitFacing(chain[l],f-180)
set l = l + 1
endloop
//Destroy==================
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set xh = GetUnitX(host)
set yh = GetUnitY(host)
if GetDisXY(GetUnitX(chain[chaini]),GetUnitY(chain[chaini]),GetUnitX(host),GetUnitY(host)) < 100 then
call RemoveUnit(chain[chaini])
set chain[chaini] = null
set chaini = chaini - 1
if chaini == -1 then
call .Destroy()
endif
endif
endif
endmethod
endstruct
private function Engine takes nothing returns nothing
local integer i = 0
local mhook h
local group g
local unit t
loop
exitwhen i > ihook
if ahook[i] != 0 then
set h = ahook[i]
//--run--//
call h.Move()
else
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = i - 1
endif
set i = i + 1
endloop
//call DestroyGroup(g)
set g = null
set t = null
endfunction
function Trig_HookC_Bool takes nothing returns boolean
if GetSpellAbilityId() == 'A01D' then //Способность Мясной хук
return true
else
return false
endif
endfunction
function Trig_HookC_Actions takes nothing returns nothing
local mhook h
set h = mhook.Create(GetSpellAbilityUnit(),GetSpellTargetX(),GetSpellTargetY(),110)
call h.Start()
endfunction
function Init_Hook takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( t, function Trig_HookC_Actions )
call TriggerAddCondition(t,function Trig_HookC_Bool)
call TimerStart(CreateTimer(),0.025,true,function Engine)
endfunction
endlibrary
Здесь не делают заказы. Насколько помню есть специальные темы для заказов. Но совершенно случайно у меня оказалась пара свободных минут
Импортировать TerrainArt\Ruins\*.blp
Вот. Есть текст про описание движения как я понял (вот в чем разница между конным и пешим пока тоже не понял, интересует вот, что дает конный)
Эти паффинги, и типы движения взаимосвязаны. У некоторых есть баги, которыми можно воспользоваться. Например, чтобы летающие юниты игнорили ландшафт и летели прямо (вот на клифах может быть криво). На форуме дофига такого. Также можно сделать нелетающих летающими, дать сфинкс или превратиться в ворона (тоже баг) Ну и так далее
Tiodor, стоп, как это по тем же точкам? При изменении положения базовой кости, разве присоединённые к ней остальные не должны меняться? В-общем не могу я исправить)) Эта модель должна заменять архивную... К какой-либо карте она не относится. Так-то =(
После усердного копания архивов игры и парочки тестов, нашёл для себя выход) В War3Patch.mpq/Units/UnitUI.slk хранились нужные мне данные. Ранее подобных проблем не было (о почему же!), поэтому и не пытался издеваться над игрой)
А с каким юнитом проблема? И в каком триггере ты регулируешь масштаб? А то лень копаться в РО и РТ
К примеру, юнит "Атрозис 2" меньше юнита "Атрозис 1", хотя в РО размер задан больше, модель стандартная. Через триггеры масштаб не регулируется. Возможно, проблема с триггерами в папке "bu", которые отвечают за мгновенное строительство и улучшение.
Всем спасибо, проблему распаковал. Проблема была действительно в триггерах, которые мгновенно достраивают здания. При улучшении, здания как бы "начинают расти", но триггер делает прогресс улучшения равным 100% и масштаб остается прежним.
Obelick, эта либо не трогает мультибоарды
она по точкам(location) в основном работает Obelick:
учить ради них джас и переписывать мне настолько лень
если ты нормально знаешь гуи и имеешь базовые знания по использованию гугл переводчика то переписать мультибоард на jass много времени не займёт
кроме того тебе не обязательно переписывать полностью
можно сконвертировать в код и поправить то что вызывает утечки
если ты говоришь об утечках в функции установки значения ячейки мультибоарда то их можно убрать следующим кодом
вставь его в шапку карты (туда где ты ALL.j подключал)
правда после этого автозаполнение строк/столбцов перестанет работать и придётся делать его циклом
Zeuz, в доте нету такого количества таймеров
во многих нормальных картах сделано так как в статьях Zeuz:
покажи пример в обычном jass
скопируй в карту а потом вытащи из неё j файл или напиши в коде букву на отдельной строке (тогда тебе выдаст ошибку и будет показан исходный код)
но на обычном джассе этот код больше и писать/читать его неудобно так что держи
Насчет дестроя группы. Она же создается один раз, если я ее уничтожу - триггер вообще выполнятся не станет, разве не так?
Это не так, она уже использовалась и стала локальной, и да. Лучше глобальную используй.
Лучше внутри таймера проверять ограниченным кол-во крипов через стек. т.е. о 0 до N ограничения, которые не повлияет на производительность. при этом проверяя на наличие их безжизненности, потом просто воссоздавая их по данным сохранённым внутри данных по юниту.
Если мобы были ранее на карте, то и ранее должны были быть зарегестрированы в массив данных, где храниться их TypeId, PosX\Y и п.р.
во первых где дебаг
во вторых не фиг вешать на хэндл таймера всякую фигню
юзай список и пробегай по нему таймером
и будет тебе счастье
в третьих если говоришь что где то ошибка ты должен указать :
строку с ошибкой
доказательства того что она произошла (скрин + лог)
собственные попытки её исправить
в четвёртых предоставить карту
короче либо предоставь всю информацию либо перепиши код по нормальному
как правильно переписать ты сможешь прочесть в статьях
native IssueImmediateOrderById takes unit whichUnit, integer order returns boolean
Создай юнитов по 1 на каждого игрока и прикажи им
call IssueImmediateOrderById(<твой юнит>, 852164)
приказ можно менять только Каналу и книге заклинаний, у остальных способностей нет смысла
Возможно порядок вызова отрабатывает не правильно. Я бы сделал немного иначе. Внутри фигуры запрашивал бы данные от кубов.
var cubeComponents = GetChildrenComponents<CubComponent>(); // получаем список дочерних компонентов типа CubeComponent
var isRightCollision = cubeComponents.Any(cube => cube.isRight); // проверяем у каждого флаг isRight и если хотя бы у одного стоит, то возврашаем true
// .. остальные действия
MadWay, любая карта это mpq архив
открываем карту в архиваторе и через блокнот меняем все названия
это даже проще чем через редактор ибо можно копировать-вставить
вот статья по некоторым файлам внутри архива
Эмм, формат w3x читаем, открываем мпк редактором и вытаскиваем необходимые файлы, редактор тут ненужен.
Погодь, Doodad Christmas - она же открыта, открой в редакторе и меняй.
с этим косяик есть. Если ты импортируешь в карту измененные с сохранения файлы, но с теми же путями - ты имеешь вероятность получить файлы с 0 байт(но чаще это только визуально 0 байт) либо остаётся старая версия. Бороться просто - переименовывать файлики в этот раз на "файл1" в следующий - обратно на "файл". Либо стараться реже реимпортировать одни и те же названия. Проверять багнулось ли лучше сразу.
Нашел ответ.
Использование mix архивов. Кидаем файлы в mix архив, сам архив в папку варкрафта, а в карте прописываем путь к файлу внутри архива. Варкрафт автоматически использует данные всех mix архивов в своей директории.
Осуществляешь импорт по неправильному пути. Например (я пробовал для орков), "Sound\Music\mp3Music\Orc1.mp3", "Sound\Music\mp3Music\Orc2.mp3", "Sound\Music\mp3Music\Orc3.mp3", "Sound\Music\mp3Music\Orc1X.mp3" и т.д. Все стандартные треки были заменены на мой. Чтобы корректно заменять музыку на карте, нужно знать пути импорта. Путь к оригинальным трекам можно посмотреть в mpq-архиве через архиваторы.
анимацию апгрейда можно проиграть
а чтоб постоянная была. то прописыают триггером тэг анимации. или видел как у Иллидана? там два юнита: охотник и демон. Посмотри как у демона сделано. там есть прописано alternate
что за костыли блин
событие - приводит способность в действие
условие - применённая способность == божественный щит
действия:
unit u=GetTriggerUnit()
SetUnitVertexColor(u,0,0,0,255)
TriggerSleepAction(15) // здесь указываем время действия способности
SetUnitVertexColor(u,255,255,255,255)
если время действия зависит от уровня то юзай арифметику как писали выше
в твоём случае это 2 + (уровень способности * 2)
через иф в действие записывать но это не кул EnergyFrost, не угадал)
и чем тебе функция не нравится?
функция Condition берёт функцию и возвращает условие
silence_AZ,
Вот вам пример, идите разбирайте его и читайте все статьи, что есть.
function UnitAddEffect takes unit u, real x, real y returns nothing
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", x, y))
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl", GetUnitX(u), GetUnitY(u)))
endfunction
function Action takes nothing returns nothing
local unit u = GetOrderedUnit()
local real x = GetOrderPointX()
local real y = GetOrderPointY()
call UnitAddEffect(u, x, y)
endfunction
function InitTrig_Effect takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
set i = i + 1
exitwhen i == 16
endloop
call TriggerAddAction( t, function Action )
endfunction
Создайте триггер "Effect", конвертируйте в текст, удалите все что там есть, копирните и вставьте мое, запускайте карту и побегайте юнитами.
То что я написал можно и нужно оптимизировать, но так как вам нужен пример создания пользовательский функций, то я сделал именно так.
Вот на всякий случай оптимизированный вариант.
SetUnitPosition довольно тяжелая операци, юзайте SetUnitX\Y в конце полета юзай SetUnitPosition для того чтобы юнит не залетел в непроходимое место.
Фильтр просто ужас, ну кто так фильтры делает?
Проверка на 'Aloc', я в ужасе на кой черт проверять на дамми если GropEnumUnitsInRange\Rect не выделяет москитов, тока EnumOfPlayer может пикнуть москитов, остальное не пикает их, на то они и москиты...
Вот как выглядит нормальный фильтр без локалок и прочего
function EnemyFilter takes nothing returns boolean
set bj_lastFilterUnit = GetFilterUnit( )
return GetUnitState( bj_lastFilterUnit, UNIT_STATE_LIFE ) > 0.405 and IsUnitEnemy( bj_lastFilterUnit, bj_groupEnumOwningPlayer ) and not( IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MAGIC_IMMUNE ) or IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MECHANICAL ) or IsUnitInvulnerable( bj_lastFilterUnit ) )
endfunction
UnitDamageTargetEx - красиво но нафиг ненужно обводить в отдельную функцию с тучей аргументов + жутко неудобно, 100500 аргументов у функции и фиг знает за что какой от вечает, прямо так UnitDamageTarget, без отдельной функции.
Туча констант, тоже хорошо тока длят наработок, на деле ставь конкретные значения или юзай Difine vjass'a.
Ещё есть вариант - тревога это реакция нейтральных монстров на то, что недалеко от них появилось здание (когда начинаешь строить здание, и тут из леса прибегают нейтралы, ломают, и убегают обратно).
первая проверка - мб эта функция делает так что данный нейтрал игнорирует то что рядом с ним появится здание, и он в итоге не побежит его атаковать
вторая проверка - возможно функция делает само здание игнорируемым для этих нейтралов, т.е. конкретно на него не будут сбегаться ближайшие нейтралы
Я удалял всеь код кроме етой системы все ефект тотже. также я писал что переносил наработку на иную мапу и там все работало. понятно что проблема не в коде..по тому как баг в том что рынок(юнит) меняет владельца, на красного скажем, еслиб не менял багаб небыло, но есть карта где он есть.. на разных мапах при абсолютно едентичных настройках юнитов, и коде(никакого второстепенного кода нет тока тот что в 1м посту)
опшем так я психанул и начал отрезать куски из мапы, сначала в 10 раз удалил весь код кроме наработки, затем удалил итемы, и вернул код и вот чудо баг пропал, =============================================================================
думаю проблема была в том что иды предметам я в ручную прописывал, там была своя закономерность, но увы теперь придется периписать все иды предметов, и заминить их в коде что очень ни удобно и моторно=(
Нашёл систему, где звук передаётся в таймер, который истекает через 0 секунд. В результате один и тот же звук может проигрываться несколько раз без всяких проблем. В инетике пишут мол это такой баг движка.
Урон настраивается через уровень способности, или как было сказано unit - damage target
команда для использования нестандартной способности берется от той способности, на основе которой ты её сделал, и если это цепь тралла - Unit - issue order with targetign a unit - orc - chain lighting
Ну решается всё довольно тривиально
Юнит атакован
приказ атакующего юнита не равен "атаковать"
б.е. - приказать атакующий ПКМ атакованного
При первой атаке произойдёт небольшая потеря времени, т.к. получив при каз юнит заново начнёт анимацию атаки. Зато орб будет прокать.
Алсо если приказать юниту перейти нападая на противников (триггерно или ручками) - приказ юнита будет какой-надо и орб будет срабатывать.
quq_CCCP, вот только это не позволит юзать книгу пока спелл не перезарядится
событие - юнит приводит способность в действие
в условии проверяем что это способность из нашего спелбука
потом триггерно нажимаем кнопку отмена(Esc)
в гуи это находится в разделе игра
называется вроде игрок нажимает отмена
в джасс это делается с помощью ForceUICancelBJ
в качестве игрока передаём владельца триггерного юнита
если это игрок а не какой нибудь AI скрипт то сработает
» WarCraft 3 / Проблема со способностью
» WarCraft 3 / Пути
» WarCraft 3 / Масштабирование модели
» WarCraft 3 / Библиотека звуков
» WarCraft 3 / call ForGroup()
» Unity / Скрипт
» WarCraft 3 / Перевод карты
» WarCraft 3 / Предмет в требованиях
» WarCraft 3 / Импорт музыки
» WarCraft 3 / Timer
» WarCraft 3 / Анимации
» WarCraft 3 / Вопрос о функции SetUnitBlendTime
» WarCraft 3 / Продать все предметы
» WarCraft 3 / ID Звука
» WarCraft 3 / Юниты атакуют и кастуют способности